
/* ------------------------------------------------------------------------
マウス移動によるキャンバススクロール

【使用方法】（なるべく<head>タグ内にて）
<script src="js/prototype.js" type="text/javascript"></script>
<script src="js/scriptaculous.js?load=effects" type="text/javascript"></script>
<script src="js/moving_canvas.js" type="text/javascript"></script>
<script language="JavaScript" type="text/javascript">
Event.observe(window,'load',function() {
	var option = {viewport:"viewport", canvas:"canvas", speed:5};
	new Moving(option); 
});
</script>

【パラメータの説明】
パラメータは以下の情報を任意に指定します（上記書式を参考に）
	viewport: 実際に表示するエリアID（ビューポート）
	canvas: 表示内容を格納するエリアID（キャンバス）
	speed: 移動スピード（加速度）　1〜10:大きいほど速い
 ※サイズは幅／高さともCSSで指定します（viewport ＜ canvas）
 ------------------------------------------------------------------------ */

var Moving = Class.create();
Moving.prototype = {

initialize: function(option) {
  this.props = {
    viewport : "viewport",
    canvas : "canvas",
    speed : 5
  };
  for (var key in option) this.props[key] = option[key];
  if (this.props.speed <  1) this.props.speed =  1;
  if (this.props.speed > 10) this.props.speed = 10;

  this.viewportDiv = $(this.props.viewport);
  this.canvasDiv = $(this.props.canvas);

  //キャンバスの情報
  this.cvWidth = this.canvasDiv.getWidth();
  this.cvHeight = this.canvasDiv.getHeight();

  //ビューポートの位置
  this.vpWidth  = this.viewportDiv.getWidth();
  this.vpHeight = this.viewportDiv.getHeight();
  var vPos = Element.cumulativeOffset(this.viewportDiv);
  this.vpLeft = vPos[0];
  this.vpTop  = vPos[1];
  
  //ビューポートセンターの位置
  this.vpCenterX = + this.vpLeft + (this.vpWidth/2);
  this.vpCenterY = + this.vpTop + (this.vpHeight/2);
  
  //ビューポート右下の位置
  this.vpRight  = + this.vpLeft + this.vpWidth;
  this.vpBottom = + this.vpTop + this.vpHeight;

  this.viewportDiv.style["overflow"] = "hidden";
  this.viewportDiv.style["position"] = "relative"; //forIE
  Event.observe(
    this.props.viewport, 'mousemove', 
    this.moveCenter.bindAsEventListener(this)
  ); // イベントを監視 
},
			
moveCenter: function (e) {
  //現在のキャンバスの位置
  var cvPos = Element.cumulativeOffset($(this.props.canvas));
  var cvLeft = cvPos[0];
  var cvTop  = cvPos[1];
 
  //現在のマウスの位置
  var mouseX = Event.pointerX(e);
  var mouseY = Event.pointerY(e);

  //移動量算出（中心からの距離）
  var dX = this.vpCenterX - mouseX;
  var dY = this.vpCenterY - mouseY;
  
  //速度を変える
  var dur = 4.0;
  dur = dur / this.props.speed;

  //端まで来たとき移動量調整
  if (dX > 0) { //left
    if (cvLeft + dX > this.vpLeft) dX = this.vpLeft - cvLeft;
  } else { //right
    if (cvLeft + dX + this.cvWidth < this.vpRight) dX = this.vpRight - cvLeft - this.cvWidth;
  }
  if (dY > 0) { //top
    if (cvTop + dY > this.vpTop) dY = this.vpTop - cvTop;
  } else { //bottom
    if (cvTop + dY + this.cvHeight < this.vpBottom) dY = this.vpBottom - cvTop - this.cvHeight;
  }

  if (Math.abs(dX) < 1 && Math.abs(dY) < 1) return;

//$('msg').innerHTML = "dX="+dX+" dY="+dY+" , duration="+dur;
//$('msg').innerHTML = "X="+mouseX+" Y="+mouseY+" , Left="+cvLeft+" Top="+cvTop;
//$('msg').innerHTML = "X="+mouseX+" Y="+mouseY+" , Left="+this.vpLeft+" Top="+this.vpTop;
  new Effect.Move(this.props.canvas,{ 
      x: dX, y: dY, duration: dur, transition: Effect.Transitions.linear, 
      scope: 'global', limit: 1, queue: 'parallel'
  });  
}

}//prototype